home *** CD-ROM | disk | FTP | other *** search
/ InfoMagic Internet Tools 1993 July / Internet Tools.iso / RockRidge / mail / mmdf / mmdf-IIb.43 / src / tools / dbmedit.c < prev    next >
Encoding:
C/C++ Source or Header  |  1990-02-28  |  8.4 KB  |  432 lines

  1. #include "util.h"
  2. #include "mmdf.h"
  3. #include "chdbm.h"
  4.  
  5. /*
  6.  * Edit the mmdf dbm database - Phil Cockcroft UCL
  7.  * From an Idea by Peter Collinson
  8.  *      Should really use the mmdf routines but it is easier to write
  9.  *      your own than to find the right ones.
  10.  */
  11.  
  12. extern char *tbldbm;
  13. extern char *tbldfldir;
  14. extern char *dupfpath();
  15. extern char *multcat();
  16. extern char *gets();
  17.  
  18. typedef struct  {
  19.     char    *dptr;
  20.     int     dsize;
  21. } datum;
  22.  
  23. extern  datum   fetch();
  24. datum   dcons();
  25.  
  26. char    ibuf[LINESIZE];
  27. char    *p;
  28. #define MARGS   100
  29. char    *argv[MARGS];                /* max number of args on a line */
  30. int     argc;
  31.  
  32. int     help(), add(), del(), change(), print(), quit();
  33.  
  34. struct  cmds    {
  35.     char    *cm_name;
  36.     int     (*cm_func)();
  37.     char    *cm_help;
  38. } cmds[] = {
  39.     "help", help,   "Print out help text",
  40.     "add",  add,    "Add an entry",
  41.     "delete", del,  "Delete an entry",
  42.     "change", change, "Change an entry",
  43.     "print", print, "Print an entry",
  44.     "quit", quit,   "Quit the program",
  45.     "h",    help,   0,              /* single character aliases */
  46.     "a",    add,    0,
  47.     "d",    del,    0,
  48.     "c",    change, 0,
  49.     "p",    print,  0,
  50.     "q",    quit,   0,
  51.     "?",    help,   0,
  52. }, *curcmd;
  53.  
  54. int    verbose;
  55.  
  56. /*
  57.  * dbm expanded structure
  58.  */
  59.  
  60. #define MDB     50
  61.  
  62. char    *dblock;
  63. int     ndbents;
  64.  
  65. struct  db      {
  66.     char    *d_table;
  67.     char    *d_value;
  68. } dbs[MDB], *lastdb;
  69.  
  70. main(ac, av)
  71. char **av;
  72. {
  73.     mmdf_init(av[0]);
  74.  
  75.     dblock = multcat (dupfpath (tbldbm, tbldfldir), ".lck", (char *)0);
  76.     (void) close( creat( dblock, 0444 ));
  77.  
  78.     while (ac > 1 && av[1][0] == '-') {
  79.         if (lexequ(av[1], "-v")) {
  80.             verbose++;
  81.             ac--;
  82.             av++;
  83.         } else if (lexequ(av[1], "-d")) {
  84.             if (ac < 3) {
  85.                 fprintf(stderr, "dbmedit: missing database path\n");
  86.                 exit(NOTOK);
  87.             }
  88.             tbldbm = av[2];
  89.             ac -= 2;
  90.             av += 2;
  91.             dblock = multcat (tbldbm, ".lck", (char *)0);
  92.             (void) close( creat( dblock, 0444 ));
  93.         } else {
  94.             fprintf(stderr, "dbmedit: unknown argument '%s'\n", av[1]);
  95.             exit(NOTOK);
  96.         }
  97.     }
  98.     if(!isstr(tbldbm)) {
  99.         fprintf(stderr, "dbmedit: cannot find database path\n");
  100.         exit(NOTOK);
  101.     }
  102.     dbfinit(tbldbm);
  103.  
  104.     /* if got command line arguments process these instead */
  105.     if(ac > 1){
  106.         avfix(ac, av);
  107.         if(findcmd() < 0)
  108.             exit(1);
  109.         exit((*curcmd->cm_func)());
  110.     }
  111.  
  112.     for(;;){
  113.         printf("dbmedit> ");
  114.         (void) fflush(stdout);
  115.         if (gets(ibuf) == NULL)
  116.             exit(0);
  117.         if (!isstr(ibuf))
  118.             continue;
  119.         p=ibuf+strlen(ibuf);
  120.         while (isspace(*--p))
  121.             *p = '\0';  /* strip trailing lwsp */
  122.         if ((argc = sstr2arg(ibuf, MARGS, argv, " \t")) == 0)
  123.             continue;
  124.         if(findcmd() < 0)
  125.             continue;
  126.         (*curcmd->cm_func)();
  127.     }
  128. }
  129.  
  130. avfix(ac, av)
  131. register char   **av;
  132. {
  133.     register char   **ap;
  134.  
  135.     for(av++, ac--, ap = argv; ac ; ac--, argc++)
  136.         *ap++ = *av++;
  137. }
  138.  
  139. findcmd()
  140. {
  141.     register struct cmds *cp;
  142.  
  143.     for(cp = cmds ; cp < &cmds[sizeof(cmds)/sizeof(cmds[0])] ; cp++)
  144.         if(lexequ(cp->cm_name, argv[0])){
  145.             curcmd = cp;
  146.             return(0);
  147.         }
  148.     fprintf(stderr, "dbmedit: unknown command '%s'\n", argv[0]);
  149.     return(-1);
  150. }
  151.  
  152. help()
  153. {
  154.     register struct cmds *cp;
  155.  
  156.     for(cp = cmds ; cp < &cmds[sizeof(cmds)/sizeof(cmds[0])] ; cp++)
  157.         if(cp->cm_help != 0)
  158.             printf("%s\t\t%s\n", cp->cm_name, cp->cm_help);
  159.     return(0);
  160. }
  161.  
  162. datum
  163. dcons(value)
  164. char    *value;
  165. {
  166.     datum d;
  167.  
  168.     d.dptr = value;
  169.     d.dsize = strlen(value)+1;
  170.     return(d);
  171. }
  172.  
  173. dssplit(str)
  174. register char   *str;
  175. {
  176.     register struct db      *dp;
  177.     static  char    ti[512];
  178.     char    *strcpy();
  179.  
  180.     ndbents = 0;
  181.     str = strcpy(ti, str);
  182.     for(dp = dbs ; dp < &dbs[sizeof(dbs)/sizeof(dbs[0])]; dp++){
  183.         if(*str == 0)
  184.             break;
  185.         dp->d_table = str;
  186.         while(*str && *str != ' ')
  187.             str++;
  188.         *str++ = 0;
  189.         dp->d_value = str;
  190.         while(*str && *str != FS)
  191.             str++;
  192.         ndbents++;
  193.         if(*str == FS)
  194.             *str++ = 0;
  195.     }
  196.     lastdb = dbs + ndbents;
  197. }
  198.  
  199. add()
  200. {
  201.     datum   d;
  202.     register struct db      *dp;
  203.  
  204.     if(argc != 4){
  205.         fprintf(stderr, "Usage: add key table value\n");
  206.         return(9);
  207.     }
  208.     d = fetch(dcons(argv[1]));
  209.     if(d.dptr == 0){
  210.         if (verbose)
  211.             printf("Creating new key: \"%s\" table: \"%s\" value: \"%s\"\n",
  212.                         argv[1], argv[2], argv[3]);
  213.         lastdb = dbs;
  214.         goto newalias;
  215.     }
  216.     dssplit(d.dptr);
  217.     if (verbose)
  218.         for(dp = dbs ; dp < lastdb ; dp++){
  219.         if(lexequ(dp->d_table, argv[2])){
  220.             fprintf(stderr,
  221.          "Warning: key \"%s\" has existing value \"%s\" in table \"%s\"\n",
  222.                     argv[1], dp->d_value, argv[2]);
  223.         }
  224.         }
  225.  
  226. newalias:;
  227.     dp = lastdb++;
  228.     dp->d_table = argv[2];
  229.     dp->d_value = argv[3];
  230.     return(dscons());
  231. }
  232.  
  233. del()
  234. {
  235.     datum   d;
  236.     register struct db      *dp;
  237.     int     changed = 0;
  238.     int    lckfd;
  239.  
  240.     if (argc < 2 || argc > 4) {
  241.         fprintf(stderr, "Usage: delete key [table [value] ]\n");
  242.         return(9);
  243.     }
  244.  
  245.     d = fetch(dcons(argv[1]));
  246.     if (d.dptr == 0) {
  247.         fprintf(stderr, "Key \"%s\" not found in database\n", argv[1]);
  248.         return(99);
  249.     }
  250.     if (argc == 2) {    /* all entries */
  251.         if (verbose)
  252.             printf("Deleting key \"%s\"\n", argv[1]);
  253.         goto delall;
  254.     }
  255.     dssplit(d.dptr);
  256.     for(dp = dbs ; dp < lastdb ; dp++) {
  257.         if(dp->d_table && lexequ(dp->d_table, argv[2]) 
  258.            && ( (argc == 3) || lexequ(dp->d_value, argv[3]) )) {
  259.             if (verbose)
  260.                 printf("Deleting \"%s\" from table \"%s\" (value: \"%s\")\n",
  261.                     argv[1], argv[2], dp->d_value);
  262.             changed++;
  263.             dp->d_table = 0;
  264.         }
  265.     }
  266.     if(!changed){
  267.         if (argc == 3)
  268.         fprintf(stderr,
  269.             "\"%s\" does not have a value in table \"%s\"\n",
  270.                         argv[1], argv[2]);
  271.         else
  272.         fprintf(stderr,
  273.             "\"%s\" does not have a value of \"%s\" in table \"%s\"\n",
  274.                         argv[1], argv[3], argv[2]);
  275.         return(99);
  276.     }
  277.     if(lastdb - changed <= dbs) {
  278.         if (verbose)
  279.             printf("All values deleted for \"%s\" - deleting key\n",
  280.                                 argv[1]);
  281. delall:        if ((lckfd = lk_open(dblock, 0, (char *)0, (char *)0, 10)) < 0) {
  282.             perror(dblock);
  283.             printf("Database %s is locked.  Try again later.\n",
  284.                  tbldbm);
  285.             return(1);
  286.         }
  287.         if(delete(dcons(argv[1])) < 0)
  288.             fprintf(stderr, "Delete failed\n");
  289.  
  290. #ifdef DBMCACHE
  291.         dbmcachedump();
  292. #endif /* DBMCACHE */
  293.  
  294.         lk_close (lckfd, dblock, (char *)0, (char *)0);
  295.         return(0);
  296.     }
  297.     return(dscons());
  298. }
  299.  
  300. change()
  301. {
  302.     datum   d;
  303.     register struct db      *dp;
  304.     int    newvalpos;
  305.  
  306.     if(argc < 4 || argc > 5) {
  307.         fprintf(stderr,
  308.             "Usage: change key table [oldvalue] newvalue\n");
  309.         return(9);
  310.     }
  311.  
  312.     newvalpos = (argc == 4) ? 3 : 4;
  313.     d = fetch(dcons(argv[1]));
  314.     if(d.dptr == 0) {
  315.         if (verbose)
  316.             fprintf(stderr, "key \"%s\" not found in database\n",
  317.                 argv[1]);
  318.         if (argc == 4)
  319.             return(add());
  320.         return(0);
  321.     }
  322.     dssplit(d.dptr);
  323.     for(dp = dbs ; dp < lastdb ; dp++)
  324.         if(lexequ(dp->d_table, argv[2])){
  325.             if ((argc == 5) && !lexequ(dp->d_value, argv[3]))
  326.                 continue;
  327.             if (verbose)
  328.                 printf("changing \"%s\" to \"%s\"\n",
  329.                         dp->d_value, argv[newvalpos]);
  330.             dp->d_value = argv[newvalpos];
  331.             break;
  332.         }
  333.  
  334.     if(dp >= lastdb){  /* no change made */
  335.         if (argc == 4)
  336.             return(add());
  337.         else {
  338.             fprintf(stderr, 
  339.                 "No entry found for key \"%s\" in table \"%s\" with value \"%s\"\n",
  340.                 argv[1], argv[2], argv[3]);
  341.             return(0);
  342.         }
  343.     }
  344.     return(dscons());
  345. }
  346.  
  347. print()
  348. {
  349.     datum   d;
  350.     register struct db      *dp;
  351.  
  352.     if(argc < 2){
  353.         fprintf(stderr, "Usage: print key [table]\n");
  354.         return(9);
  355.     }
  356.  
  357.     d = fetch(dcons(argv[1]));
  358.     if(d.dptr == 0){
  359.         fprintf(stderr, "key \"%s\" not found in database\n", argv[1]);
  360.         return(99);
  361.     }
  362.     dssplit(d.dptr);
  363.     for(dp = dbs ; dp < lastdb ; dp++)
  364.         if (argc == 2 || lexequ(dp->d_table, argv[2]) ||
  365.             lexequ("*", argv[2]))
  366.             printf("key \"%s\": table \"%s\": value \"%s\"\n",
  367.                 argv[1], dp->d_table, dp->d_value);
  368.     return(0);
  369. }
  370.  
  371. dscons()
  372. {
  373.     char    tbuf[ENTRYSIZE];
  374.     datum   d;
  375.     register struct db      *dp;
  376.     register char   *p, *q;
  377.     int     changed = 0;
  378.     int    lckfd;
  379.  
  380.     for(p = tbuf, dp = dbs ; dp <lastdb ; dp++){
  381.         if((q = dp->d_table) == 0)
  382.             continue;
  383.         if(p != tbuf)
  384.             *(p-1) = FS;
  385.         changed++;
  386.         while(*p++ = *q++);
  387.         *(p-1) = ' ';
  388.         for(q = dp->d_value ; *p++ = *q++;);
  389.     }
  390.     if (!changed) {
  391.         fprintf(stderr, "dbmedit: internal error 'no change'\n");
  392.         return(99);
  393.     }
  394.     d = dcons(tbuf);
  395.  
  396.     if ((lckfd = lk_open(dblock, 0, (char *)0, (char *)0, 10)) < 0) {
  397.         perror (dblock);
  398.         printf("Database %s is locked.  Try again later.\n", tbldbm);
  399.         return(1);
  400.     }
  401.     if (store(dcons(argv[1]), d) < 0) {
  402.         fprintf(stderr, "dbmedit: cannot store new value for '%s'\n", argv[1]);
  403.     }
  404.  
  405. #ifdef DBMCACHE
  406.     dbmcachedump();
  407. #endif /* DBMCACHE */
  408.  
  409.     lk_close (lckfd, dblock, (char *) 0, (char *)0);
  410.     return(0);
  411. }
  412.  
  413. /*
  414.  * Initialize the dbm file.
  415.  */
  416.  
  417. dbfinit(filename)
  418. char *filename;
  419. {
  420.     if(dbminit(filename) < 0) {
  421.         fprintf (stderr, "could not initialize data base '%s'", filename);
  422.         perror("");
  423.         exit(99);
  424.     }
  425.     return (0);
  426. }
  427.  
  428. quit()
  429. {
  430.     exit(0);
  431. }
  432.